package de.hypoport.einarbeitung.scrumspirit.persistence.genericdao;

import java.util.Collection;
import java.util.List;

/**
 * Base interface for all DAOs. To use, extend it in DAO interfaces.
 *
 * @param <K>
 *            The primary key class of the entity, e.g. Long.
 * @param <E>
 *            The entity class the DAO persists, e.g. Person.
 */
public interface Dao<K, E> {
    /**
	 * Save the entity.
	 *
	 * @param entity
	 *            The persistence entity to save.
	 */
	public void store(E entity);

    /**
	 * Save the Collection of entities.
	 *
	 * @param entities
	 *            The Collection of persistence entities to save.
	 */
	public void persist(Collection<E> entities);

    /**
	 * Merge the entity.
	 *
	 * @param entity
	 *            The persistence entity to merge.
	 * @return The merged entity.
	 */
    E merge(E entity);

    /**
	 * Delete the entity.
	 *
	 * @param entity
	 *            The persistence entity to delete.
	 */
    void remove(E entity);

    /**
	 * Delete the entity for the specified primary key.
	 *
	 * @param id
	 *            The id (primary key) of the entity to delete.
	 */
    void removeById(K id);

    /**
	 * Delete the entity for the specified primary key, optionally throwing an
	 * exception if not found (this prevents <code>NullPointerException</code>s
	 * from occurring later).
	 *
	 * @param id
	 *            The id (primary key) of the entity to delete.
	 * @param exceptionIfNotFound
	 *            true to throw an exception if entity not found.
	 */
    void removeById(K id, boolean exceptionIfNotFound);

    /**
	 * Find an entity by its id, and return null if not found.
	 *
	 * @param id
	 *            The id (primary key) of the entity to find.
	 * @return The entity for the specified id, null when entity not found.
	 */
    E findById(K id);

    /**
	 * Find all entities.
	 *
	 * @return List of all entities.
	 */
    List<E> findAll();

    /**
	 * Find all entities starting in the resultset specified by startPosition
	 * and obtaining up to the number specified by maxResult. This method is
	 * useful for pagination of results.
	 *
	 * @param startPosition
	 *            The starting position in the result set to retrieve.
	 * @param maxResult
	 *            The maximum number of rows to retrieve.
	 * @return List of a subset of all entities, starting with startPosition and
	 *         containing up to maxResult entries.
	 */
    List<E> findAll(int startPosition, int maxResult);

    /**
     * Synchronize the underlying persistent store with persistable state held
     * in memory.
     */
    void flush();

    /**
     * Clear the in-memory persistable state, including unflushed changes.
     */
    void clear();

    /**
	 * Check if the entity belongs to the current persistence context.
	 *
	 * @param entity
	 *            The persistence entity to see if exists.
	 * @return true if the entity belongs to the current persistence context.
	 */
    boolean contains(E entity);

    /**
	 * Reload the entity.
	 *
	 * @param entity
	 *            The persistence entity to reload from the persistence context.
	 */
    void refresh(E entity);

    /**
	 * Count all values represented by the entity class this DAO persists (no
	 * where clause, no path expression).
	 *
	 * @return Long representing number of values in the group.
	 */
    Long countAll();

    /**
	 * Count all values represented by the specified where clause for the entity
	 * class this DAO persists.
	 * <p>
	 * This convenience method is meant for simple count queries. For complex
	 * ones, create custom ones in the product DAOs.
	 * </p>
	 *
	 * @param where
	 *            See where param for #countAll(String, String)
	 * @return Long representing number of values in the group.
	 */
    Long countAll(String where);

    /**
	 * Count all values represented by the specified where clause and
	 * pathExpression for the entity class this DAO persists.
	 * <p>
	 * This convenience method is meant for simple count queries. For complex
	 * ones, create custom ones in the product DAOs.
	 * </p>
	 *
	 * @param where
	 *            The where clause to append to the count query to narrow the
	 *            counted values. Do not prefix with "where" as it is
	 *            automatically added. The underlying query uses "e" as the
	 *            identification variable, so the where will use "e", e.g.
	 *            "e.name = 'Fred'". Specifying null disregards a where clause.
	 * @param pathExpression
	 *            A String representing the object graph navigation to the
	 *            element to count. The underlying query uses "e" as the
	 *            identification variable, so the pathExpression will u "e",
	 *            e.g. "e.address.zip", "e.name", "e.id". Specify either an
	 *            identification variable (e.g. "e") or a path expression (e.g.
	 *            "e.address.zip"). Specifying null disregards a pathExpression
	 *            (defaults to "*").
	 * @return Long representing number of values in the group.
	 */
    Long countAll(String where, String pathExpression);
}
